# coding: utf-8
from django.shortcuts import render,redirect
from store.models import *
from django.conf import settings
import logging
from store.forms import *
from django.core.paginator import Paginator,InvalidPage,EmptyPage,PageNotAnInteger
from django import forms
from django.contrib.auth import logout,login,authenticate
from django.contrib.auth.hashers import make_password
from django.db.models import F
from django import template
from django.http import HttpResponse,Http404
from django.shortcuts import render,render_to_response
from django.template import Context,loader
from django.views.generic import View,TemplateView,ListView,DetailView
from django.db.models import Q
from django.core.cache import caches

from shangcheng.settings import PAGE_NUM

from django.core.exceptions import PermissionDenied


try:
    cache = caches['memcache']
except ImportError as e:
    cache = caches['default']

#logger
logger = logging.getLogger(__name__)

class BaseMixin(object):
    def get_context_data(self,*args,**kwargs):
        context = super(BaseMixin,self).get_context_data(**kwargs)
        try:
            #热门文章
            context['hot_article_list']=Article.objects.order_by("-view_times")[0:10]
            #导航条
            context['nax_list'] = Nav.objects.filter(status=0)


        except Exception as e:
            logger.error(u'[BaseMixin]加载基本信息出错')

        return context
class IndexView(BaseMixin,ListView):
    template_name = 'index2.html'
    context_object_name = 'article_list'
    paginate_by = PAGE_NUM

    def get_context_data(self, **kwargs):
        # 轮播
        kwargs['carousel_page_list'] = Carousel.objects.all()
        return super(IndexView, self).get_context_data(**kwargs)

    def get_queryset(self):
        article_list = Article.objects.filter(status=0)
        return article_list

class ArticleView(BaseMixin,DetailView):
    queryset = Article.objects.filter(status=0)
    template_name = 'article.html'
    context_object_name = 'article'
    slug_field = 'en_title'

    def get(self,request,*args,**kwargs):
        #统计文章的访问次数
        if 'HTTP_X_FORWARDED_FOR' in request.META:
            ip = request.META['HTTP_X_FORWARDED_FOR']
        else:
            ip = request.META['REMOTE_ADDR']
        self.cur_user_ip = ip

        en_title = self.kwargs.get('slug')
        #获取15*60s时间内访问过这篇文章的所有ip
        visited_ips = cache.get(en_title,[])
        #如果ip不存在就把文章的浏览次数+1
        if ip not in visited_ips:
            try:
                article = self.queryset.get(en_title=en_title)
            except Article.DoseNotExist:
                logger.error(u'[ArticleView]访问不存在的文章：[%s]'%en_title)
                raise Http404
            else:
                article.view_times += 1
                article.save()
                visited_ips.append(ip)

            #更新缓存
            cache.set(en_title,visited_ips,15*60)
        return super(ArticleView,self).get(request,*args,**kwargs)



class AllView(BaseMixin,ListView):
    template_name = 'all.html'
    context_object_name = 'article_list'
    def get_context_data(self,**kwargs):
        kwargs['category_list'] = Category.objects.all()
        kwargs['PAGE_NUM'] = PAGE_NUM
        return super(AllView,self).get_context_data(**kwargs)
    def get_queryset(self):
        article_list = Article.objects.filter(status=0)[0:PAGE_NUM]
        return article_list
    def post(self,request,*args,**kwargs):
        val = self.request.POST.get('val','')

        sort = self.request.POST.get('sort','time')
        start = self.request.POST.get('start','0')
        end = self.request.POST.get('end',PAGE_NUM)
        start = int(start)
        end = int(end)
        if sort =='time':
            sort = '-pub_time'
        elif sort =='recommend':
            sort ='-view_times'
        if val =='all':
            article_list = Article.objects.filter(status=0).order_by(sort)[start:end+1]
        else:
            try:
                article_list =Category.objects.get(name=val).article_set.filter(status=0).order_by(sort)[start:end+1]
            except Category.DoesNotExist:
                logger.error(u'[ALLView]此分类不存在：[%s]'%val)
                raise PermissionDenied
        isend = len(article_list) != (end-start+1)
        article_list = article_list[0:end-start]
        html = ''
        for article in article_list:
            html += template.loader.get_template('include/all_post.html').render(template.Context({'post':article}))

        mydict = {'html':html,'isend':isend}
        return HttpResponse(json.dumps(mydict),content_type="application/json")
class SearchView(BaseMixin,ListView):
    template_name = 'search.html'
    context_object_name = 'article_list'
    paginate_by = PAGE_NUM
    def get_context_data(self,**kwargs):
        kwargs['s'] = self.request.GET.get('s','')
        return super(SearchView,self).get_context_data(**kwargs)
    def get_queryset(self):
        #获取搜索关键字
        s = self.request.GET.get('s',)
        #在文章的标题，summarg和tags中搜索关键字
        article_list = Article.objects.only('title', 'summary', 'tags') \
            .filter(Q(title__icontains=s) | Q(summary__icontains=s) | Q(tags__icontains=s)\
            ,status=0);
        return article_list



class TagView(BaseMixin,ListView):
    template_name = 'tag.html'
    context_objects_name= 'article_list'
    paginate_by = PAGE_NUM

    def get_queryset(self):
        tag = self.kwargs.get('tag','')
        article_list =Article.objects.only('tags').filter(tags_icontains=tag,status=0)
        return article_list

class CateView(BaseMixin,ListView):
    template_name = 'category.html'
    context_object_name = 'article_list'
    paginate_by=PAGE_NUM

    def get_queryset(self):
        cate =self.kwargs.get('category','')
        try:
            article_list =Cate.objects.get(name=cate).article_set.all()
        except Cate.DoesNotExist:
            logger.error(u'[CateView]此分类不存在：[%s]'%cate)
            raise Http404
        return article_list

logger = logging.getLogger('store.views')





def authenticated_view(function):
  def wrap(request, *args, **kwargs):
      if request.user.is_authenticated():
          return function(request)
      else:
        login_form = LoginForm()
        return render(request, 'login.html', locals())

  wrap.__doc__=function.__doc__
  wrap.__name__=function.__name__
  return wrap

def global_setting(request):
    #站点信息
    MEDIA_URL = settings.MEDIA_URL
    category_list = Category.objects.all()
    # 记事本分类信息
    category_list_m = [c for c in category_list if c.sex == 0]
    # 钱包分类信息
    category_list_f = [c for c in category_list if c.sex == 1]

    #热销榜

    hot_list = Clothing.objects.all().order_by('-sales')[:4]
    #购物车
    cart = request.session.get(request.user.id, None)
    return locals()

#主页
def index(request):

    clo_list = Clothing.objects.all()
    clo_list = getPage(request,clo_list)
    anli_list=Anli.objects.all()
    anli_list = anli_getPage(request,anli_list)
    article_list = Article.objects.all()
    cate_list= Cate.objects.all()
    return render(request,"index.html",locals())

#案例列表
def anli_list(request):
    try:
        cid = request.GET.get('cid',None)
        try:
            category = Cateanli.objects.get(pk=cid)
        except Cateanli.DoesNotExist:
            return render(request, 'error.html', {"reason":"分类不存在"})
        anli_list = Anli.objects.filter(category=category)
        anli_list = getPage(request,anli_list)
    except Exception as e:
        logger.error(e)
    return render(request, 'anli_list.html', locals())

#产品列表页
def products(request):
    try:
        cid = request.GET.get('cid',None)
        try:
            category = Category.objects.get(pk=cid)
        except Category.DoesNotExist:
            return render(request, 'error.html', {"reason":"分类不存在"})
        clo_list = Clothing.objects.filter(category=category)
        clo_list = getPage(request,clo_list)
    except Exception as e:
        logger.error(e)
    return render(request, 'products.html', locals())

#案例详情页
def anli_detail(request):
    try:
        did = request.GET.get('did', None)
        try:
            anli = Anli.objects.get(pk=did)
        except Anli.DoesNotExist:
            return render(request, 'error.html', {"reason":"案例不存在"})
    except Exception as e:
        logger.error(e)
    return render(request, 'anli_detail.html', locals())

#商品详情页
def detail(request):
    try:
        did = request.GET.get('did', None)
        try:
            clo = Clothing.objects.get(pk=did)
        except Clothing.DoesNotExist:
            return render(request, 'error.html', {"reason":"商品不存在"})
    except Exception as e:
        logger.error(e)
    return render(request, 'single.html', locals())


#注册
def do_reg(request):
    try:
        if request.method == 'POST':
            reg_form = RegForm(request.POST)
            if reg_form.is_valid():
                user = User.objects.create(username=reg_form.cleaned_data["username"],
                                    email=reg_form.cleaned_data["email"],
                                    password=make_password(reg_form.cleaned_data["password"]),)
                user.save()
                user.backend = 'django.contrib.auth.backends.ModelBackend'
                login(request,user)
                return redirect(request.POST.get('source_url'))
            else:
                return render(request,'error.html',{'reason': reg_form.errors})
        else:
            reg_form = RegForm()
    except Exception as e:
        logger.error(e)
    return render(request,'register.html',locals())

#登录
def do_login(request):
    try:
        if request.method == 'POST':
            login_form = LoginForm(request.POST)
            if login_form.is_valid():
                username = login_form.cleaned_data["username"]
                password = login_form.cleaned_data["password"]
                user = authenticate(username=username,password=password)
                if user is not None:
                    user.backend = 'django.contrib.auth.backends.ModelBackend' # 指定默认的登录验证方式
                    login(request, user)
                else:
                    return render(request,'error.html',{'reason': '登录验证失败'})
                return redirect(request.POST.get('source_url'))
            else:
                return render(request, 'error.html', {'reason': login_form.errors})
        else:
            login_form = LoginForm()
    except Exception as e:
        logger.error(e)
    return render(request, 'login.html', locals())





#退出
def do_logout(request):
    try:
        logout(request)
    except Exception as e:
        logger.error(e)
    login_form = LoginForm()
    return render(request, 'login.html', locals())

#查看购物车
@authenticated_view
def view_cart(request):
    cart = request.session.get(request.user.id, None)
    return render(request, 'checkout.html', locals())

#添加购物车
@authenticated_view
def add_cart(request):
    try:
        chid = request.POST.get('chid',None)
        try:
            clothing = Clothing.objects.get(pk=chid)
        except Clothing.DoesNotExist:
            return render(request, 'error.html', {'reason':'商品不存在'})
        cart = request.session.get(request.user.id,None)
        if not cart:
            cart = Cart()
            cart.add(clothing)
            request.session[request.user.id] = cart
        else:
            cart.add(clothing)
            request.session[request.user.id] = cart
    except Exception as e:
        logger.error(e)
    return render(request, 'checkout.html', locals())

#清空购物车
@authenticated_view
def cleanCart(request):
    cart = Cart()
    request.session[request.user.id] = cart
    return render(request, 'checkout.html', locals())

@authenticated_view
def clean_one_item(request, id):
    item = None
    try:
     item = Clothing.objects.get(pk=id)
    except Clothing.DoesNotExist:
        pass
    if item:
        item.delete()
    cart = request.session.get(request.user.id, None)
    return render(request, 'checkout.html', {'cart':cart})

#打折商品
def getDiscount(request):
    try:
        clo_list = Clothing.objects.filter(new_price__lt=F('old_price'))
        clo_list = getPage(request,clo_list)
        logger.debug("len clo_list:%d", len(clo_list))
        discount = True
    except Exception as e:
        logger.error(e)
    return render(request, 'products.html', locals())


#分页
def getPage(request,clo_list):
    paginator = Paginator(clo_list,10)
    try:
        page = int(request.GET.get('page',1))
        clo_list = paginator.page(page)
    except (EmptyPage,InvalidPage,PageNotAnInteger):
        clo_list = paginator.page(1)
    return clo_list

#分页
def anli_getPage(request,anli_list):
    paginator = Paginator(anli_list,8)
    try:
        page = int(request.GET.get('page',1))
        anli_list = paginator.page(page)
    except (EmptyPage,InvalidPage,PageNotAnInteger):
        anli_list = paginator.page(1)
    return anli_list